using System;
using System.Collections.Generic;
using UnityEngine.Rendering;

public enum EventEnum
{

}

public class EventManager : Singleton<EventManager>
{
    #region Event Class

    private interface IEventInfo { }

    public class EventInfo : IEventInfo
    {
        public Action action;

        public EventInfo()
        {

        }

        public EventInfo(Action action)
        {
            this.action = action;
        }
    }

    private class EventInfo<T> : IEventInfo
    {
        public Action<T> action;

        public EventInfo()
        {

        }

        public EventInfo(Action<T> action)
        {
            this.action = action;
        }
    }

    #endregion

    private Dictionary<EventEnum, IEventInfo> EventDic = new Dictionary<EventEnum, IEventInfo>();

    #region AddEventListener

    public void AddEventListener(EventEnum eventEnum, Action action)
    {
        if(EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo).action += action;
        }
        else
        {
            eventInfo = new EventInfo(action);
            EventDic.Add(eventEnum, eventInfo);
        }
    }

    public void AddEventListener<T>(EventEnum eventEnum, Action<T> action)
    {
        if (EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo<T>).action += action;
        }
        else
        {
            eventInfo = new EventInfo<T>(action);
            EventDic.Add(eventEnum, eventInfo);
        }
    }

    #endregion

    #region RemoveEventListener

    public void RemoveEventListener(EventEnum eventEnum, Action action)
    {
        if(EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo).action -= action;
        }
    }

    public void RemoveEventListener<T>(EventEnum eventEnum, Action<T> action)
    {
        if (EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo<T>).action -= action;
        }
    }

    #endregion

    #region ExcuteEvent

    public void ExcuteEvent(EventEnum eventEnum)
    {
        if(EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo).action?.Invoke();
        }
    }

    public void ExcuteEvent<T>(EventEnum eventEnum, T arg)
    {
        if (EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo<T>).action?.Invoke(arg);
        }
    }

    #endregion

    #region DeleteEvent

    public void DeleteEvent(EventEnum eventEnum)
    {
        if(EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo).action = null;
            EventDic.Remove(eventEnum);
        }
    }

    public void DeleteEvent<T>(EventEnum eventEnum)
    {
        if (EventDic.TryGetValue(eventEnum, out IEventInfo eventInfo))
        {
            (eventInfo as EventInfo<T>).action = null;
            EventDic.Remove(eventEnum);
        }
    }

    #endregion
}
